import java.util.LinkedList ;
import java.util.Vector ;

public class MapNeuron extends SkeletalNeuronFramework {
    private double a = .5 , b = 1.5 , c = .04 ;
    
    public MapNeuron( ) {
        String [ ] params = { "a" , "b" , "c" } ;
        
        // initially at a random membrane potential between -1 and 1
        setPotential( 0. , 2 * Math.random( ) - 1 ) ;
        
        parameterNames = params ;
    }
    
    public String getParam( String name ) {
        if ( name.equals( "a" ) ) {
            return "" + a ;
        } else if ( name.equals( "b" ) ) {
            return "" + b ;
        } else if ( name.equals( "c" ) ) {
            return "" + c ;
        } else {
            return null ;
        }
    }
    
    public String getName( ) {
        return "1-d Map Neuron" ;
    }
    
    public void setParam( String name , String data ) {
        double value ;
        
        // all parameters are doubles
        try {
            value = Double.parseDouble( data ) ;
        } catch ( NumberFormatException e ) {
            // not a double; ignore the set request
            return ;
        }
        if ( name.equals( "a" ) ) {
            a = value ;
        } else if ( name.equals( "b" ) ) {
            b = value ;
        } else if ( name.equals( "c" ) ) {
            c = value ;
        }
    }
    
    
    public INeuron clone( ) {
        MapNeuron n = new MapNeuron( ) ;
        n.setParam( getParams( ) ) ;
        return n ;
    }
    
    private double f( double v ) {
        if ( v < -1 ) return 0 ;
        if ( v < .2 ) return a * v ;
        if ( v < .85 ) return b * v - .1 ;
        return c * ( v - 1 ) ;
    }
    
    
    public void advance( ) {
        double v = getPotential( ) + Iapp.amount( time ) ;
        double vnew ;
        
        // add synaptic currents
        for ( ISynapse s : syn ) {
            v += s.strength( ) * s.getPreCell().getPotential( time - s.getDelay( ) ) ;
        }
        
        time ++ ;
        vnew = f( v ) ;
        setPotential( time , f( v ) ) ;
        if ( vnew > .5 && v <= .5 ) {
            lastSpike = time ;
        }
    }
    
    // test driver
    public static void main( String args [] ) {
        MapNeuron neuron = new MapNeuron( ) ;
        Curve c ;
        int i ;
        
        // set neuron's initial potential just over threshhold
        neuron.setPotential( 0 , .21 ) ;
        
        // run for 30 time steps
        for ( i = 0 ; i < 30 ; i ++ ) {
            neuron.advance( ) ;
        }
        
        c = neuron.getCurve( ) ;
        c.isVisible = true ;
        
        Graph g = new Graph( ) ;
        g.addCurve( c ) ;
        g.setWindow( 0 , -.5 , 30 , 1.1 ) ;
        
        g.makeWindow( 640 , 480 , Graph.QUIT_ON_CLOSE , "Map Neuron" ) ;
    }
}
